﻿Imports System.Windows.Forms
Imports DirectShowLib
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Drawing.Imaging
Imports UCBase
Imports System.Drawing

Public Class CamSelect
    Private capDevices As DsDevice()
    Private SelectedDevice As Integer
    Private SelectedMode As Integer
    Private m_FilterGraph As IFilterGraph2 = Nothing
    Private m_pinStill As IPin = Nothing

    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub CamSelect_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)
        Dim C As Integer = 0
        DeviceCombo.Items.Clear()
        For Each Dev As DsDevice In capDevices
            DeviceCombo.Items.Add("[" & C & "] " & Dev.Name)
            C = C + 1
        Next
    End Sub

    Private Sub DeviceCombo_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DeviceCombo.SelectedIndexChanged
        SelectedDevice = DeviceCombo.SelectedIndex
        GetResolutions()
    End Sub
    Private Sub GetResolutions()
        Dim hr As Integer
        Dim dev As DsDevice = capDevices(SelectedDevice)
        Dim capFilter As IBaseFilter = Nothing
        m_FilterGraph = TryCast(New FilterGraph(), IFilterGraph2)
        ModeCombo.Items.Clear()
        Try
            hr = m_FilterGraph.AddSourceFilterForMoniker(dev.Mon, Nothing, dev.Name, capFilter)
            DsError.ThrowExceptionForHR(hr)
            m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Still, 0)
            If m_pinStill Is Nothing Then
                m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Preview, 0)
            End If
            If m_pinStill Is Nothing Then
                m_pinStill = DsFindPin.ByCategory(capFilter, PinCategory.Capture, 0)
            End If

            Dim streamConfig As IAMStreamConfig = DirectCast(m_pinStill, IAMStreamConfig)
            Dim searchmedia As AMMediaType = Nothing
            Dim ptr As IntPtr

            Dim piCount As Integer, piSize As Integer
            hr = streamConfig.GetNumberOfCapabilities(piCount, piSize)
            ptr = Marshal.AllocCoTaskMem(piSize)
            For i As Integer = 0 To piCount - 1
                hr = streamConfig.GetStreamCaps(i, searchmedia, ptr)
                Dim vinfo As New VideoInfoHeader()
                Marshal.PtrToStructure(searchmedia.formatPtr, vinfo)
                If vinfo.BmiHeader.Width > 0 Then
                    ModeCombo.Items.Add("[" & i & "] = " & vinfo.BmiHeader.Width & " X " & vinfo.BmiHeader.Height & "(" & vinfo.BmiHeader.BitCount & ")" & " FPS:" & CInt(10000000 / vinfo.AvgTimePerFrame))
                    ModeCombo.Enabled = True
                End If
            Next

        Catch
        End Try

        If m_FilterGraph IsNot Nothing Then
            Marshal.ReleaseComObject(m_FilterGraph)
            m_FilterGraph = Nothing
        End If

        If m_pinStill IsNot Nothing Then
            Marshal.ReleaseComObject(m_pinStill)
            m_pinStill = Nothing
        End If
    End Sub

    Private Sub ModeCombo_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ModeCombo.SelectedIndexChanged
        Dim str As String = ModeCombo.SelectedItem
        Dim a As Integer = str.IndexOf("[") + 1
        Dim b As Integer = str.IndexOf("]")
        Dim l As Integer = b - a
        Dim n As String = str.Substring(a, l)
        SelectedMode = CInt(Val(n))

    End Sub
    Public Property Device() As Integer
        Get
            Return SelectedDevice
        End Get
        Set(ByVal value As Integer)
            SelectedDevice = value
            DoUpdate()
        End Set
    End Property
    Public Property Mode() As Integer
        Get
            Return SelectedMode
        End Get
        Set(ByVal value As Integer)
            SelectedMode = value
            DoUpdate()
        End Set
    End Property
    Private Sub DoUpdate()
        capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)
        Dim C As Integer = 0
        DeviceCombo.Items.Clear()
        For Each Dev As DsDevice In capDevices
            DeviceCombo.Items.Add("[" & C & "] " & Dev.Name)
            C = C + 1
        Next
        DeviceCombo.SelectedIndex = SelectedDevice
        ModeCombo.SelectedIndex = SelectedMode
    End Sub
End Class
